﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

using AwesomeEnginePC.Physics;

namespace AwesomeEnginePC.Graphics.TwoDimensional.Sprites
{
    public class BaseSprite : Base2DObject
    {
        /// <summary>
        /// The sprite image to show.
        /// </summary>
        public Texture2D SpriteTexture { get; protected set; }

        /// <summary>
        /// The SpriteEffects that are in effect on the object (if applicable).
        /// </summary>
        public virtual SpriteEffects EffectsOnSprite { get; set; }

        /// <summary>
        /// Returns the height of the sprite texture loaded. This is the height of the sprite if the ScalingY was 1.
        /// </summary>
        public override int RawHeight
        {
            get { return SpriteTexture.Height; }
        }

        /// <summary>
        /// Returns the width of the sprite texture loaded. This is the width of the sprite if the ScalingY was 1.
        /// </summary>
        public override int RawWidth
        {
            get { return SpriteTexture.Width; }
        }

        public BaseSprite(ContentManager CM, string assetName)
            : base(CM)
        {
            SetDefaultValues();
            SetSpriteTexture(assetName);
        }

        public BaseSprite(ContentManager CM, String assetName, Vector<int> position, Color tint)
            : base(CM)
        {
            SetSpriteTexture(assetName);
            Position = position;
            Tint = tint;

            SetDefaultValues();
        }

        public BaseSprite(ContentManager CM, BaseSpriteSettings settings)
            : base(CM)
        {
            SetDefaultValues();
            LoadFromSettings(settings);
        }

        protected override void SetDefaultValues()
        {
            base.SetDefaultValues(); //because it's virtual
            EffectsOnSprite = SpriteEffects.None;
        }

        public void SetSpriteTexture(string assetName)
        {
            SpriteTexture = LoadContent<Texture2D>(assetName);
        }

        public void SetTexturePixels(Color[] pixels)
        {
            SpriteTexture.SetData(pixels);
        }

        public BaseSpriteSettings GetBaseSpriteSettings()
        {
            BaseSpriteSettings bss = (BaseSpriteSettings)base.GetBase2DObjectSettings();
            bss.EffectsOnSprite = this.EffectsOnSprite;
            bss.SpriteTexture = this.SpriteTexture;
            return bss;
        }

        public void LoadFromSettings(BaseSpriteSettings settings)
        {
            base.LoadFromSettings((Base2DObjectSettings)settings);

            EffectsOnSprite = settings.EffectsOnSprite;

            if (settings.SpriteTexture != null)
                SetSpriteTexture(settings.SpriteTexture.Name);
        }

        public void LoadFromSettings(Base2DObjectSettings settings, SpriteEffects effectsOnSprite, string assetName)
        {
            base.LoadFromSettings(settings);

            EffectsOnSprite = effectsOnSprite;

            if (assetName != null)
                SetSpriteTexture(assetName);
        }     

        public override void Update(GameTime gameTime)
        {
            
        }

        protected override void DrawInner(GameTime gameTime, SpriteBatch sb)
        {
            sb.Draw(SpriteTexture, Position.ToVector2(), null, Tint, Rotation, Origin.ToVector2(), Scaling.ToVector2(), EffectsOnSprite, LayerDepth);
        }

        /// <summary>
        /// Tells if the given point is within the sprite as it drawn to the screen (scaling is taken into consideration)
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public virtual bool IsPointOnSprite(Vector<int> point)
        {
            return (point.X >= this.Position.X && point.X <= (this.Position.X + this.Width)) && 
                   (point.Y >= this.Position.Y && point.Y <= (this.Position.Y + this.Height));
        }
    }
}
